package cn.yogehaoren.badfox.spring.common;

import cn.yogehaoren.badfox.core.BadFoxDownloadInterceptor;
import cn.yogehaoren.badfox.core.BadFoxInterceptor;
import cn.yogehaoren.badfox.def.BaseBadFox;
import cn.yogehaoren.badfox.exception.BadFoxProcessExcepiton;
import cn.yogehaoren.badfox.struct.CrawlerModel;
import cn.yogehaoren.badfox.struct.Request;
import cn.yogehaoren.badfox.struct.Response;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;


public class BadFoxCache {

    private final static  List<BadFoxInterceptor> interceptors = new CopyOnWriteArrayList<>();
    private final static List<BadFoxDownloadInterceptor> downloadInterceptors = new CopyOnWriteArrayList<>();
    private final static Set<Class<? extends BaseBadFox>> crawlers = new CopyOnWriteArraySet<>();
    private final static Map<String,CrawlerModel> crawlerModelContext  = new ConcurrentHashMap<>();
    private static ExecutorService threadPool;
    private static boolean springBoot = true;
    private static ThreadLocal<Response> responseContext = new ThreadLocal<>();



    static void addInterceptor(BadFoxInterceptor badFoxInterceptor) {
        interceptors.add(badFoxInterceptor);
    }

    static void addDownloadInterceptor(BadFoxDownloadInterceptor interceptor){
        downloadInterceptors.add(interceptor);
    }

    static void addCrawler(Class<? extends BaseBadFox> crawlerClass) {
        crawlers.add(crawlerClass);
    }

    public static List<BadFoxInterceptor> getInterceptors(){
        //对拦截器按照设定的权重进行倒序排序，如：88,66,11
        interceptors.sort((o1, o2) -> o1.getWeight() > o2.getWeight() ? -1 : 1);
        return interceptors;
    }

    public static List<BadFoxDownloadInterceptor> getDownloadInterceptors() {

        //对网络拦截器按照设定的权重进行倒序排序，如：88,66,11
        downloadInterceptors.sort((o1, o2) -> o1.getWeight() > o2.getWeight() ? -1 : 1);
        return downloadInterceptors;
    }

    static public Set<Class<? extends BaseBadFox>> getCrawlers(){
        return crawlers;
    }

    public static Map<String, CrawlerModel> getCrawlerModelContext() {
        return crawlerModelContext;
    }

    public static CrawlerModel getCrawlerModel(String crawlerName) {
        return crawlerModelContext.get(crawlerName);
    }

    static void putCrawlerModel(String name,CrawlerModel model){
        crawlerModelContext.put(name,model);
    }

    static boolean isExist(String crawlerName){
        return crawlerModelContext.containsKey(crawlerName);
    }

    public static boolean isSpringBoot() {
        return springBoot;
    }


    public static void consumeRequest(Request request){
        if (request == null){
            throw new BadFoxProcessExcepiton("reques can not be null");
        }
        CrawlerModel crawlerModel = getCrawlerModel(request.getCrawlerName());
        if (crawlerModel == null){
            throw new BadFoxProcessExcepiton("can not find any crawler named '"+request.getCrawlerName()+"'.");
        }
        crawlerModel.sendRequest(request);
    }

    public static ExecutorService getThreadPool() {
        return threadPool;
    }

    static void setThreadPool(ExecutorService threadPool) {
        BadFoxCache.threadPool = threadPool;
    }

    public static void setResponseContext(Response response){
        responseContext.set(response);
    }

    public static Response getResponseFromContext(){
        return responseContext.get();
    }

    public static void clearResponseContext(){
        responseContext.remove();
    }

}
